from datetime import datetime
from pywebsite.controller_paddleocr import get_ocr_result
from pywebsite.controller_paddleocr import get_ocr_result_img
from PIL import Image, ImageFile
from decimal import Decimal
import decimal
import re


def check_receipt_amount_date(amount, date, filepath, shop, holder=0.5, debug=False):
    result1 = get_ocr_result(filepath)
    # 生产环境有[0] result = result1[0]
    result = result1[0]
    date_check = False
    amount_check = False
    illegal_check = False
    check_result = []
    for line in result:
        if check_amount(amount, line[1][0]) and line[1][1] > holder:
            amount_check = True
            # line[1][0] = line[1][0]+" - 匹配到金额"
            check_result.append(line)

        if check_date(date, line[1][0]) and line[1][1] > holder:
            date_check = True
            # line[1][0] = line[1][0]+" - 匹配到日期"
            check_result.append(line)
        if check_illegal(line[1][0]) and line[1][1] > holder:
            illegal_check = True
            check_result.append(line)
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    image = Image.open(filepath).convert('RGB')
    if debug:
        new_result = result
    else:
        new_result = check_result
    boxes = [line[0] for line in result]
    txts = [line[1][0] for line in result]
    scores = [line[1][1] for line in result]
    ret_img = get_ocr_result_img(image, boxes, txts, scores)

    if illegal_check:
        return -3, ret_img
    if date_check and amount_check:
        boxes = [line[0] for line in new_result]
        txts = [line[1][0] for line in new_result]
        scores = [line[1][1] for line in new_result]
        ret_img = get_ocr_result_img(image, boxes, txts, scores)
        return 1, ret_img
    if date_check:
        return -1, ret_img
    if amount_check:
        return -2, ret_img

    return 0, ret_img


def check_date(date, rec_str):
    #  数字匹配 20220911 2022911  11092022 1192022  220911 22911 110922 11922
    num_str = "".join(re.findall("\d*", rec_str))
    #    date_str = datetime.strftime(date,'%Y%m%d')
    #    date_str2 = datetime.strftime(date, '%Y%-m%-d')
    # 220911 22911
    date_str = datetime.strftime(date, '%y%m%d')  # 年月日，带前导零
    date_str2 = f"{date.year % 100}{date.month}{date.day}"  # 年月日，去掉前导零
    # 11092022 1192022
    date_str3 = datetime.strftime(date, '%d%m%Y')  # 日月年，带前导零
    date_str4 = f"{date.day}{date.month}{date.year}"  # 日月年，去掉前导零
    # 110922 11922
    date_str5 = datetime.strftime(date, '%d%m%y')  # 日月年，带前导零（两位年）
    date_str6 = f"{date.day}{date.month}{date.year % 100}"  # 日月年，去掉前导零（两位年）

    if num_str.find(date_str) >= 0 or num_str.find(date_str2) >= 0:
        return True
    if num_str.find(date_str3) >= 0 or num_str.find(date_str4) >= 0:
        return True
    if num_str.find(date_str5) >= 0 or num_str.find(date_str6) >= 0:
        return True

    # 英文月份支持
    mouthstr = datetime.strftime(date, '%b')
    # 032022
    date_str7 = datetime.strftime(date, '%d%Y')
    # 202203
    date_str8 = datetime.strftime(date, '%Y%d')
    # 32022
    date_str9 = f"{date.day}{date.year}"  # 去掉前导零: 32022
    # 20223
    date_str10 = f"{date.year}{date.day}"  # 去掉前导零: 20223
    # 0322
    date_str11 = datetime.strftime(date, '%d%y')
    # 2203
    date_str12 = datetime.strftime(date, '%y%d')
    # 322
    date_str13 = f"{date.day}{date.year % 100}"  # 去掉前导零: 322
    # 223
    date_str14 = f"{date.year % 100}{date.day}"  # 去掉前导零: 223

    #  有月份
    if str.upper(rec_str).find(str.upper(mouthstr)) >= 0:
        # 有年日
        if num_str.find(date_str7) >= 0 or num_str.find(date_str8) >= 0 \
                or num_str.find(date_str9) >= 0 or num_str.find(date_str10) >= 0 \
                or num_str.find(date_str11) >= 0 or num_str.find(date_str12) >= 0 \
                or num_str.find(date_str13) >= 0 or num_str.find(date_str14) >= 0:
            return True
    return False


def check_amount(amount, rec_str):
    if amount==0:
        return False
    rec_str = check_half_string(rec_str)
    nums = re.findall("\d+[.]?\d*", rec_str.replace(",", ""))
    for num in nums:
        if len(num) > 10:
            continue
        if amount == Decimal(num):
            return True
        # 抹零
        if amount == Decimal(num).quantize(0, rounding=decimal.ROUND_FLOOR):
            return True
        # 直接进位
        if amount == Decimal(num).quantize(0, rounding=decimal.ROUND_CEILING):
            return True
        # 四舍五入
        if amount == Decimal(num).quantize(0, rounding=decimal.ROUND_HALF_UP):
            return True
    return False


def check_illegal(rec_str):
    return "顾客惠存" in rec_str


# 可能将金额识别双份
def check_half_string(s):
    """
    严格验证并返回半边字符串：
    - 长度>12且为偶数
    - 两半完全相同
    - 每半是数字且恰好2个'.'
    """
    # 1. 检查长度
    if len(s) <= 12 or len(s) % 2 != 0:
        return s

    # 2. 对半拆分
    half_len = len(s) // 2
    first_half = s[:half_len]
    second_half = s[half_len:]

    # 3. 检查两半一致性
    if first_half != second_half:
        return s

    # 4. 严格检查数字和2个'.'
    if not re.fullmatch(r'^\d+\.\d+$', first_half):  # 必须匹配 "X.Y.Z" 格式
        return s

    return first_half
